#pragma once

// 
// Created By: Xiaofeng.Gu 2021/03/18
// 

#include "Defines.hpp"


struct TaskRunnerPoolClientNode
{
	SocketBasePtr pSender;
	std::string groupId;
	std::string id;
	std::string type;
	std::string description;
	std::string userData;
	std::string tag;
	std::vector<std::string>	tagList;
	

	TaskRunnerPool::ETaskRunnerPoolState state;
	long long lockTimestamp;
	long long deleteTimestamp;

	void send(Message& msg) {
		pSender->send(msg);
	}
};
class CybertronTaskRunnerPoolServer : public SocketTcpServer
{
public:

	CybertronTaskRunnerPoolServer();
	virtual ~CybertronTaskRunnerPoolServer();

	bool initialize();

	void run();

	void queueControlCommand(
		SocketBasePtr pSender,
		const Message& msg);

	void OnDisConnectClient(SocketBasePtr pSender, TaskRunnerPoolClientNode* pNodeInfo);

	void Destroy();	
public:
	TaskRunnerPoolClientNode* FindClientNode(string groupId, string id,string type);
	void DeleteClientNode(string groupId, string id, string type);
	bool GetFreeTaskNodes(string groupId, string type, std::vector<TaskRunnerPoolClientNode>& nodes);
	bool GetAlllTaskNodes(string groupId, string type, std::vector<TaskRunnerPoolClientNode>& nodes);
	string GetKey(string groupId, string id, string type);
	
	bool UpdateNodeState( std::string groupId,  std::string type,  std::string id, TaskRunnerPool::ETaskRunnerPoolState state);
	bool SetAllNodeLock2Free();


	
protected:
	void runCheckNodeStatusThread();
	long long getNow();
	virtual void onAccept(SocketBasePtr pRemoteSocket);

protected:
	struct Command {
		SocketBasePtr pSender;
		Message msg;

		void swap(Command& rhs)
		{
			std::swap(pSender, rhs.pSender);
			msg.swap(rhs.msg);
		}
	};
	void RunControlCommands();
	void executeControlCommand(Command& cmd);

	void zeroMembers();
	void clearThis();
protected:
	void onHandleNodeRegisterRequestMessage(Command& cmd);
	void onHandleNodeStateMessage(Command& cmd);

protected:
	void sendStateMessage(SocketBasePtr pSend, std::string groupId, std::string id, std::string type,TaskRunnerPool::ETaskRunnerPoolState state);

private:
	ConcurrentQueue<Command> mControlCommandQueue;

	
	typedef std::map <std::string, TaskRunnerPoolClientNode*> NodeMap;
	std::mutex mNodeMapLock;
	NodeMap mNodeMap;

	typedef std::vector <TaskRunnerPoolClientNode*> NodeList;
	NodeList mNodeDeleteList;
	std::atomic<bool> mStopped;

private:
	bool IsExistNode(std::string groupId, std::string id, std::string type);

};